-- @brief TRDP Protocol dissector plugin
-- @author Air
-- @date 2019.08

-- 创建一个新的协议结构
-- 第一个参数是协议名称会体现在过滤器中，第二个参数是协议的描述信息，无关紧要
-- 支持wireshark 3.0，其中ProtoField.uint32()里的第一个参数不能带小数点，不能叫data

local TRDP = Proto("trdp", "TRDP Protocol")

-- 解析函数
function TRDP.dissector (tvb, pinfo, tree)
end

-- 向 wireshark 注册协议插件被调用的条件
DissectorTable.get("udp.port"):add(20548, TRDP)
DissectorTable.get("udp.port"):add(17224, TRDP)


-- 创建field，第一个引号里做过滤用，第二个做显示用
local fields = TRDP.fields
fields.SeqCounter = ProtoField.uint32("SeqCounter", "序号计数器")
fields.ver = ProtoField.bytes("ver", "协议版本",base.DOT)
fields.mode = ProtoField.uint16("mode", "通讯模式",base.HEX,{ [0x5072] = "PD Request",[0x5070] = "PD Reply",[0x5064] = "PD Data",[0x5065] = "PD Error"} )
fields.comID = ProtoField.uint32("comID", "comID端口")
fields.Len = ProtoField.uint32("Len", "数据长度")
fields.CRC = ProtoField.uint32("CRC", "校验码", base.HEX)
fields.appdata = ProtoField.bytes("appdata", "应用数据", base.SPACE)

-- dissect packet
-- 下面定义 foo 解析器的主函数，这个函数由 wireshark调用
-- 第一个参数是 Tvb 类型，表示的是需要此解析器解析的数据
-- 第二个参数是 Pinfo 类型，是协议解析树上的信息，包括 UI 上的显示
-- 第三个参数是 TreeItem 类型，表示上一级解析树
function TRDP.dissector (tvb, pinfo, tree)

-- 在上一级解析树上创建 foo 的根节点
    local subtree = tree:add(TRDP, tvb())
    local offset = 0
    local tvb_len = tvb:len()
	
    -- show protocol name in protocol column（列表中可以显示TRDP名称）
    pinfo.cols.protocol = TRDP.name
    
    -- dissect field one by one, and add to protocol tree
    --    local type = tvb(offset, 1)
    --    subtree:add(fields.type, type)
    --    subtree:append_text(", type: " .. type:uint())
    --    offset = offset + 1
    
	-- add_le为小端序，add为大端序
    subtree:add(fields.SeqCounter, tvb(offset, 4))
    offset = offset + 4
    subtree:add(fields.ver, tvb(offset, 2))
    offset = offset + 2
    subtree:add(fields.mode, tvb(offset, 2))
    offset = offset + 2
    subtree:add(fields.comID, tvb(offset, 4))
	offset = offset + 12
	subtree:add(fields.Len, tvb(offset, 4))
	offset = offset + 16
	subtree:add(fields.CRC, tvb(offset, 4))
	offset = offset + 4
	
	-- 计算消息内容的长度
	local content_len = tvb_len-offset
	subtree:add(fields.appdata, tvb(offset, content_len))
	
end